package com.ayf.payment.game.api.utils;

import com.alibaba.fastjson.JSONObject;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.spec.SecretKeySpec;
import java.security.Key;
import java.security.Security;

/**
 * 与支付网关通信的AES加解密方法
 */
public final class AESCoder {
    //DES java只支持56位,BC支持64位
    //3DES,java只支持112位，168位，后8位都是奇偶验证位，而BC支持128,192位 全是密钥，无验证位
    //AES 支持密钥是128位，192位，256位
    //IDEA 只支持128位，数据块是64位

    //改变以下三个参数，可实现 DES，DESede，AES,IDEA主注对称算法的实现  IDEA 国际数据加密标准

    public static final String KEY_ALGORITHM    = "AES";
    public static final String CIPHER_ALGORITHM = "AES/ECB/PKCS5Padding";
    public static final int    keyLength        = 128;
    public static final String chargeSet = "UTF-8";

    static {
        Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider());
    }

    public static Key toKey(byte[] key) throws Exception {
        SecretKey secretKey = new SecretKeySpec(key, KEY_ALGORITHM);
        return secretKey;
    }

    //加密
    static byte[] encrypt(byte[] data, byte[] key) throws Exception {
        //还原密钥
        Key k = toKey(key);
        //实例化
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        // Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC");
        //初始化，设置加密模式
        cipher.init(Cipher.ENCRYPT_MODE, k);
        //执行
        return cipher.doFinal(data);
    }

    /**
     * 加密方法
     * @param data
     * @param pwd
     * @return
     * @throws Exception
     */
    public static String aes128EncryptUtf8(String data,String pwd) throws Exception {
        return Base64.encode(encrypt(data.getBytes(chargeSet),pwd.getBytes(chargeSet)));
    }

    /**
     * 解密方法
     * @param encryptData
     * @param pwd
     * @return
     * @throws Exception
     */
    public static String aes128DecryptUtf8(String encryptData,String pwd) throws Exception {
        return new String(decrypt(Base64.decode(encryptData),pwd.getBytes(chargeSet)));
    }


    //解密
    public static byte[] decrypt(byte[] data, byte[] key) throws Exception {
        //还原密钥
        Key k = toKey(key);
        //实例化
        Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM);
        //  Cipher cipher = Cipher.getInstance(CIPHER_ALGORITHM, "BC");
        //初始化，设置加密模式
        cipher.init(Cipher.DECRYPT_MODE, k);
        //执行
        return cipher.doFinal(data);
    }

    public static void main(String[] args) throws Exception {
        //与C++ aes_128_ecb_encrypt 配合使用
        JSONObject jsonObject = new JSONObject();
        jsonObject.put("name","你好");
        String waitEncryptdata = jsonObject.toJSONString();
        String pwd = EncryptedRandomKey.getEncryptedRandomKey();
        System.err.println("JAVA加密前报文="+waitEncryptdata);
        System.err.println("JAVA加密密码="+pwd+"\n");
        String javaEncryptData = AESCoder.aes128EncryptUtf8(waitEncryptdata,pwd);
        System.err.println("JAVA加密后报文="+javaEncryptData);
        System.err.println("JAVA解密后="+ AESCoder.aes128DecryptUtf8(javaEncryptData,pwd));

    }
}
